package manager.modulo.ordemservico.dao;

import java.sql.*;
import java.util.HashMap;
import java.util.LinkedList;
import manager.auxiliares.Format;
import manager.auxiliares.MensagemExcessao;
import manager.interfaces.InterfaceDao;
import manager.modulo.ordemservico.enumerator.EnumAvaliacaoOrdemServico;
import manager.modulo.ordemservico.enumerator.EnumAvaliacaoOrdemServico.AvaliacaoOS;
import manager.modulo.ordemservico.enumerator.EnumSituacaoOrdemServico;
import manager.principal.fonte.JanelaLogin;

/**
 * Esta classe será utilizada para cadastra a entidade user no banco de dados
 *
 * @author Thiago
 */
public class AvaliacaoOrdemServicoDao implements InterfaceDao {

    private int id;
    private int idUsuario;
    private Timestamp dataAvaliacao;
    private String comentario;
    private AvaliacaoOS avaliacaoA1;
    private AvaliacaoOS avaliacaoA2;
    private AvaliacaoOS avaliacaoA3;
    private AvaliacaoOS avaliacaoB1;
    private AvaliacaoOS avaliacaoB2;
    private AvaliacaoOS avaliacaoB3;
    private int idOrdemServico;

    /**
     * Inicializando as variáveis
     */
    public AvaliacaoOrdemServicoDao() {
        id = 0;
        idUsuario = 0;
        dataAvaliacao = new Timestamp(00 - 00 - 00);
        comentario = "";
        avaliacaoA1 = AvaliacaoOS.NAOENCONTRADO;
        avaliacaoA2 = AvaliacaoOS.NAOENCONTRADO;
        avaliacaoA3 = AvaliacaoOS.NAOENCONTRADO;
        avaliacaoB1 = AvaliacaoOS.NAOENCONTRADO;
        avaliacaoB2 = AvaliacaoOS.NAOENCONTRADO;
        avaliacaoB3 = AvaliacaoOS.NAOENCONTRADO;
        idOrdemServico = 0;
    }

    public static LinkedList<Integer> buscarOSAvaliadas(int idUnidadeAtendimento, Timestamp dataIniico, Timestamp dataFim) {
        try {

            String sql = "SELECT"
                    + "  os.id AS id"
                    + " FROM"
                    + "  avaliacao_ord_serv aos "
                    + "  INNER JOIN ordem_servico os ON os.id = aos.id_ord_serv "
                    + "  INNER JOIN situacao_ord_serv sos ON sos.id_ord_serv = os.id"
                    + "  INNER JOIN ponto_atendimento po ON po.id = os.id_pont_atend "
                    + "  INNER JOIN unidade_atendimento ua ON ua.id = po.id_unidade_atendimento"
                    + " WHERE"
                    + "  os.fl_avaliada = 1"
                    + "  AND sos.cd_situacao = ?"
                    + "  AND sos.fl_ativo = 1"
                    + "  AND ua.id = ?"
                    + "  AND sos.dt_modificacao >= ?"
                    + "  AND sos.dt_modificacao <= ?"
                    + " ORDER BY "
                    + "  os.id";
            PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql);
            preparedStatement.setInt(1, EnumSituacaoOrdemServico.ConverterEnumNumero(EnumSituacaoOrdemServico.SituacaoOS.FINALIZADA));
            preparedStatement.setInt(2, idUnidadeAtendimento);
            preparedStatement.setTimestamp(3, dataIniico);
            preparedStatement.setTimestamp(4, dataFim);
            ResultSet resultSet = preparedStatement.executeQuery();
            LinkedList<Integer> listaId = new LinkedList<Integer>();
            while (resultSet.next()) {
                listaId.add(resultSet.getInt("id"));
            }
            resultSet.close();
            preparedStatement.close();
            return listaId;
        } catch (Exception e) {
            MensagemExcessao.mostrarMensagem(e, "Avaliação de Orden de Serviço");
            return new LinkedList<Integer>();
        }
    }

    public static HashMap buscarResumoAvaliacao(LinkedList<Integer> listaOS) {
        try {
            String sql = "SELECT"
                    + "  COUNT(aos.cd_avaliacao_a1) AS quantidade,"
                    + "  SUM(aos.cd_avaliacao_a1) AS avaliacaoA1,"
                    + "  SUM(aos.cd_avaliacao_a2) AS avaliacaoA2,"
                    + "  SUM(aos.cd_avaliacao_a3) AS avaliacaoA3,"
                    + "  SUM(aos.cd_avaliacao_b1) AS avaliacaoB1,"
                    + "  SUM(aos.cd_avaliacao_b2) AS avaliacaoB2,"
                    + "  SUM(aos.cd_avaliacao_b3) AS avaliacaoB3"
                    + " FROM"
                    + "  avaliacao_ord_serv aos "
                    + " WHERE "
                    + " aos.id_ord_serv IN (";
            HashMap hashMap = new HashMap();
            if (listaOS.size() > 0) {
                for (int i = 0; i < listaOS.size(); i++) {
                    sql += "?";
                    if (i + 1 != listaOS.size()) {
                        sql += ",";
                    }
                }
                sql += ")";
                PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql);
                for (int i = 0; i < listaOS.size(); i++) {
                    preparedStatement.setInt(i + 1, listaOS.get(i));
                }

                ResultSet resultSet = preparedStatement.executeQuery();
                if (resultSet.first()) {
                    hashMap.put("quantidade", resultSet.getInt("quantidade"));
                    hashMap.put("avaliacaoA1", resultSet.getInt("avaliacaoA1"));
                    hashMap.put("avaliacaoA2", resultSet.getInt("avaliacaoA2"));
                    hashMap.put("avaliacaoA3", resultSet.getInt("avaliacaoA3"));
                    hashMap.put("avaliacaoB1", resultSet.getInt("avaliacaoB1"));
                    hashMap.put("avaliacaoB2", resultSet.getInt("avaliacaoB2"));
                    hashMap.put("avaliacaoB3", resultSet.getInt("avaliacaoB3"));
                }
                resultSet.close();
                preparedStatement.close();

            }
            return hashMap;
        } catch (Exception e) {
            MensagemExcessao.mostrarMensagem(e, "Resumo de Avaliação");
            return new HashMap();
        }
    }

    public static LinkedList buscaTabela(int idUnidadeAtendimento) throws SQLException {
        LinkedList result = new LinkedList();
        String sql = "SELECT"
                + "  os.id AS Id,"
                + "  pa.tx_identificador AS PontoAtendimento,"
                + "  sos.cd_situacao AS Situacao,"
                + "  sos.dt_modificacao AS Modificacao,"
                + "  psos.dt_modificacao AS Cadastro,"
                + "  u.tx_nome AS Usuario"
                + " FROM "
                + "  ordem_servico os"
                + "  INNER JOIN ponto_atendimento pa ON pa.id = os.id_pont_atend"
                + "  INNER JOIN unidade_atendimento ua ON ua.id = pa.id_unidade_atendimento"
                + "  INNER JOIN situacao_ord_serv sos ON sos.id_ord_serv = os.id AND sos.fl_ativo = true"
                + "  INNER JOIN usuario u ON u.id = sos.id_usuario "
                + "  INNER JOIN situacao_ord_serv psos ON psos.id_ord_serv = os.id AND psos.cd_situacao = ? "
                + " WHERE "
                + "  os.fl_nec_avaliacao = 1"
                + "  AND os.fl_avaliada = 0"
                + "  AND sos.cd_situacao = ?"
                + "  AND ua.id = ?"
                + " ORDER BY "
                + "  os.id";
        PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql);
        preparedStatement.setInt(1, EnumSituacaoOrdemServico.ConverterEnumNumero(EnumSituacaoOrdemServico.SituacaoOS.EMABERTO));
        preparedStatement.setInt(2, EnumSituacaoOrdemServico.ConverterEnumNumero(EnumSituacaoOrdemServico.SituacaoOS.FINALIZADA));
        preparedStatement.setInt(3, idUnidadeAtendimento);
        ResultSet resultSet = preparedStatement.executeQuery();

        LinkedList<String> numeroOs = new LinkedList<String>();
        LinkedList<String> pontoAtendimento = new LinkedList<String>();
        LinkedList<String> dataCadastro = new LinkedList<String>();
        LinkedList<String> ultimaModificacao = new LinkedList<String>();
        LinkedList<String> usuario = new LinkedList<String>();
        LinkedList<String> situacao = new LinkedList<String>();
        LinkedList<Integer> columnId = new LinkedList<Integer>();

        while (resultSet.next()) {
            columnId.add(resultSet.getInt("Id"));
            numeroOs.add(resultSet.getString("Id"));
            pontoAtendimento.add(resultSet.getString("PontoAtendimento"));
            dataCadastro.add(Format.formatTimeStampToCompleteDatetime(resultSet.getTimestamp("Cadastro")));
            ultimaModificacao.add(Format.formatTimeStampToCompleteDatetime(resultSet.getTimestamp("Modificacao")));
            situacao.add(EnumSituacaoOrdemServico.ConvertEnumString(EnumSituacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("Situacao"))));
            usuario.add(resultSet.getString("Usuario"));
        }

        result.add(columnId);
        result.add(Format.getBooleanLinkedList(columnId.size()));
        result.add(numeroOs);
        result.add(pontoAtendimento);
        result.add(dataCadastro);
        result.add(ultimaModificacao);
        result.add(usuario);
        result.add(situacao);
        return result;
    }

    /**
     * Carregar as informações do objeto Avaliacao Ordem Servico a partir de um
     * id
     *
     * @param id Id do Avaliacao buscada
     */
    public void buscar(int id) {
        try {
            setId(id);
            String sql = "SELECT * FROM avaliacao_ord_serv WHERE id = ?";
            PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql);
            preparedStatement.setInt(1, id);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.first()) {
                idUsuario = resultSet.getInt("id_usuario");
                dataAvaliacao = resultSet.getTimestamp("dt_avaliacao");
                comentario = resultSet.getString("tx_nome");
                avaliacaoA1 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_a1"));
                avaliacaoA2 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_a2"));
                avaliacaoA3 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_a3"));
                avaliacaoB1 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_b1"));
                avaliacaoB2 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_b2"));
                avaliacaoB3 = EnumAvaliacaoOrdemServico.ConverterNumeroEnum(resultSet.getInt("cd_avaliacao_b3"));
                idOrdemServico = resultSet.getInt("id_ord_serv");
            }
            resultSet.close();
            preparedStatement.close();
        } catch (Exception e) {
            MensagemExcessao.mostrarMensagem(e, "Buscando Avaliações");
        }
    }

    /**
     * Insere um usuário no banco
     */
    public void inserir() throws SQLException {
        String sql = "INSERT INTO avaliacao_ord_serv (id_usuario,dt_avaliacao,tx_comentario,cd_avaliacao_a1,cd_avaliacao_a2,cd_avaliacao_a3,cd_avaliacao_b1,cd_avaliacao_b2,cd_avaliacao_b3,id_ord_serv) VALUES (?,?,?,?,?,?,?,?,?,?)";
        PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);

        preparedStatement.setInt(1, idUsuario);
        preparedStatement.setTimestamp(2, dataAvaliacao);
        preparedStatement.setString(3, comentario);
        preparedStatement.setInt(4, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA1));
        preparedStatement.setInt(5, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA2));
        preparedStatement.setInt(6, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA3));
        preparedStatement.setInt(7, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB1));
        preparedStatement.setInt(8, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB2));
        preparedStatement.setInt(9, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB3));
        preparedStatement.setInt(10, idOrdemServico);
        preparedStatement.executeUpdate();

        //Recebendo o novo id gerado
        ResultSet resultSet = preparedStatement.getGeneratedKeys();
        while (resultSet.next()) {
            id = resultSet.getInt(1);
        }

        preparedStatement.close();
        resultSet.close();
    }

    /**
     * Atualiza o usuário no banco
     */
    public void atualizar() throws SQLException {
        String sql = "UPDATE avaliacao_ord_serv SET id_usuario = ? , dt_avaliacao = ? ,"
                + " tx_comentario = ? , cd_avaliacao_a1 = ? , cd_avaliacao_a2 = ? , cd_avaliacao_a3 = ? ,"
                + " cd_avaliacao_b1 = ? , cd_avaliacao_b2 = ? , cd_avaliacao_b3 = ? , id_ord_serv = ? WHERE id = ?";
        PreparedStatement preparedStatement = JanelaLogin.getConnection().prepareStatement(sql);
        preparedStatement.setInt(1, idUsuario);
        preparedStatement.setTimestamp(2, dataAvaliacao);
        preparedStatement.setString(3, comentario);
        preparedStatement.setInt(4, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA1));
        preparedStatement.setInt(5, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA2));
        preparedStatement.setInt(6, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoA3));
        preparedStatement.setInt(7, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB1));
        preparedStatement.setInt(8, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB2));
        preparedStatement.setInt(9, EnumAvaliacaoOrdemServico.ConverterEnumNumero(avaliacaoB3));
        preparedStatement.setInt(10, idOrdemServico);
        preparedStatement.setInt(11, id);
        preparedStatement.executeUpdate();
        preparedStatement.close();
    }

    public void deletar() throws SQLException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public AvaliacaoOS getAvaliacaoA1() {
        return avaliacaoA1;
    }

    public void setAvaliacaoA1(AvaliacaoOS avaliacaoA1) {
        this.avaliacaoA1 = avaliacaoA1;
    }

    public AvaliacaoOS getAvaliacaoA2() {
        return avaliacaoA2;
    }

    public void setAvaliacaoA2(AvaliacaoOS avaliacaoA2) {
        this.avaliacaoA2 = avaliacaoA2;
    }

    public AvaliacaoOS getAvaliacaoA3() {
        return avaliacaoA3;
    }

    public void setAvaliacaoA3(AvaliacaoOS avaliacaoA3) {
        this.avaliacaoA3 = avaliacaoA3;
    }

    public AvaliacaoOS getAvaliacaoB1() {
        return avaliacaoB1;
    }

    public void setAvaliacaoB1(AvaliacaoOS avaliacaoB1) {
        this.avaliacaoB1 = avaliacaoB1;
    }

    public AvaliacaoOS getAvaliacaoB2() {
        return avaliacaoB2;
    }

    public void setAvaliacaoB2(AvaliacaoOS avaliacaoB2) {
        this.avaliacaoB2 = avaliacaoB2;
    }

    public AvaliacaoOS getAvaliacaoB3() {
        return avaliacaoB3;
    }

    public void setAvaliacaoB3(AvaliacaoOS avaliacaoB3) {
        this.avaliacaoB3 = avaliacaoB3;
    }

    public String getComentario() {
        return comentario;
    }

    public void setComentario(String comentario) {
        this.comentario = comentario;
    }

    public Timestamp getDataAvaliacao() {
        return dataAvaliacao;
    }

    public void setDataAvaliacao(Timestamp dataAvaliacao) {
        this.dataAvaliacao = dataAvaliacao;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getIdOrdemServico() {
        return idOrdemServico;
    }

    public void setIdOrdemServico(int idOrdemServico) {
        this.idOrdemServico = idOrdemServico;
    }

    public int getIdUsuario() {
        return idUsuario;
    }

    public void setIdUsuario(int idUsuario) {
        this.idUsuario = idUsuario;
    }

    public LinkedList<String> buscar(String opcao, String buscado, boolean limite) throws SQLException {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
